package com.mlethe.wifitest;

import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.mlethe.wifitest.decration.LinearItemDecoration;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.mlethe.wifitest.SocketManager.SOCKET_CLOSE_ERR;
import static com.mlethe.wifitest.SocketManager.SOCKET_CLOSE_OK;
import static com.mlethe.wifitest.SocketManager.SOCKET_CONNECT_SUCCESS;
import static com.mlethe.wifitest.SocketManager.SOCKET_RECEIVE;
import static com.mlethe.wifitest.SocketManager.SOCKET_UNEXPECTED_CLOSE;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView sendIpTv, connectStatusTv, ipTv, receiveContentTv, connectedNumTv;
    private EditText portEt, sendContentEt;
    private RecyclerView recyclerView;

    private MainAdapter adapter;

    private List<Receive> dataList = new ArrayList<>();

    private SharedPreferences sharedPreferences;
    private SharedPreferences.Editor edit;

    private List<SocketManager> mItems = new ArrayList<>();

    private int mPort;

    public SocketManager mSocketManager;
    private ServerSocket mServerSocket;

    private int connectedNum = 0;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == SOCKET_CONNECT_SUCCESS) {
                clearIsClosed();
                mSocketManager = (SocketManager) msg.obj;
                mItems.add(mSocketManager);
                InetAddress address = mSocketManager.getInetAddress();
                sendIpTv.setText(address.getHostAddress());
                connectStatusTv.setText("连接成功");
                connectedNumTv.setText(String.valueOf(++ connectedNum));
            } else if (msg.what == SOCKET_RECEIVE) {
                String msgStr = (String) msg.obj;
                receiveContentTv.setText(msgStr);
                dataList.add(new Receive(msgStr, new Date()));
                adapter.notifyItemInserted(dataList.size() - 1);
            } else if (msg.what == SOCKET_CLOSE_ERR) {
                clearIsClosed();
                if (connectedNum >= 1) {
                    connectedNumTv.setText(String.valueOf(-- connectedNum));
                }
                connectStatusTv.setText("关闭异常");
            } else if (msg.what == SOCKET_CLOSE_OK) {
                clearIsClosed();
                if (connectedNum >= 1) {
                    connectedNumTv.setText(String.valueOf(-- connectedNum));
                }
                connectStatusTv.setText("断开连接");
            } else if (msg.what == SOCKET_UNEXPECTED_CLOSE) {
                clearIsClosed();
                if (connectedNum >= 1) {
                    connectedNumTv.setText(String.valueOf(-- connectedNum));
                }
                connectStatusTv.setText("客户端断开连接");
            }
        }
    };

    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            try {
                mServerSocket = new ServerSocket(mPort);
            } catch (Exception e) {
                e.printStackTrace();
            }
            synchronized (mServerSocket) {
                while (true) {
                    // accept方法会阻塞，直到有客户端与之建立连接
                    if (!mServerSocket.isClosed()) {
                        try {
                            Socket socket = mServerSocket.accept();
                            new Thread(SocketManager.create(socket, mHandler)).start();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sharedPreferences = getSharedPreferences("wifitest", Context.MODE_PRIVATE);
        edit = sharedPreferences.edit();

        mPort = sharedPreferences.getInt("port", 8080);
        new Thread(runnable).start();

        // Example of a call to a native method
        sendIpTv = findViewById(R.id.send_ip_tv);
        sendIpTv.setOnClickListener(this);
        connectStatusTv = findViewById(R.id.connect_status_tv);
        ipTv = findViewById(R.id.ip_tv);
        portEt = findViewById(R.id.port_et);
        receiveContentTv = findViewById(R.id.receive_content_tv);
        sendContentEt = findViewById(R.id.send_content_et);
        connectedNumTv = findViewById(R.id.connected_num_tv);
        recyclerView = findViewById(R.id.receive_history_rv);
        findViewById(R.id.port_btn).setOnClickListener(this);
        findViewById(R.id.send_btn).setOnClickListener(this);

        portEt.setText(mPort + "");

        adapter = new MainAdapter(this, dataList);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(adapter);
    }

    /**
     * 清理已关闭的连接
     */
    public void clearIsClosed() {
        for (int i = 0; i < mItems.size(); i++) {
            SocketManager sm = mItems.get(i);
            if (sm.isClosed()) {
                mItems.remove(i);
                sendIpTv.setText(sm.getInetAddress().getHostAddress());
                return;
            }
        }
    }

    /**
     * 创建弹窗
     */
    public void createDialog() {
        if (mItems.size() <= 0) {
            return;
        }
        List<String> list  = new ArrayList<>();
        for (int i = 0; i < mItems.size(); i++) {
            SocketManager sm = mItems.get(i);
            if (sm.isClosed()) {
                mItems.remove(i);
                i--;
                continue;
            }
            list.add(sm.getInetAddress().getHostAddress());
        }
        if (list.size() <= 0) {
            return;
        }
        final String[] items = new String[list.size()];
        for (int i = 0; i < items.length; i++) {
            items[i] = list.get(i);
        }
        new AlertDialog.Builder(this)
                .setItems(items, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        mSocketManager = mItems.get(which);
                        sendIpTv.setText(mSocketManager.getInetAddress().getHostAddress());
                        connectStatusTv.setText("已连接");
                    }
                })
                .show();
    }

    /**
     * 启动socket
     */
    private void startSocket() {
        try {
            mServerSocket = new ServerSocket(mPort);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void stopSocket() {
        try {
            mSocketManager.close();
            mServerSocket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        connectedNum = 0;
        connectedNumTv.setText(String.valueOf(connectedNum));
    }

    @Override
    protected void onResume() {
        super.onResume();
        String ipAddress = IPUtil.getIPAddress(this);
        if (ipAddress != null) {
            ipTv.setText(ipAddress);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.port_btn) {  // 更新
            String str = portEt.getText().toString().trim();
            if (!TextUtils.isEmpty(str)) {
                if (Integer.valueOf(str) == mPort) {
                    return;
                }
                mPort = Integer.valueOf(str);
                edit.putInt("port", mPort);
                edit.commit();
                stopSocket();
                startSocket();
            } else {
                Toast.makeText(this, "端口不能为空", Toast.LENGTH_SHORT).show();
            }
        } else if (id == R.id.send_btn) {   // 发送
            String str = sendContentEt.getText().toString().trim();
            if (!TextUtils.isEmpty(str)) {
                sendMsg(str);
            } else {
                Toast.makeText(this, "发送内容不能为空", Toast.LENGTH_SHORT).show();
            }
        } else if (id == R.id.send_ip_tv) { // 已连接的IP
            createDialog();
        }
    }

    private void sendMsg(String str) {
        if (mSocketManager != null) {
            mSocketManager.send(str);
        }
    }

}
